package th;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Mark
 * @version 1.0
 * @date 2020/5/24 10:55
 * @description 线程同步(抢票 / 吃饭 ( 排队 - 队列 - 锁) / 并发操作 / 对象等待池)
 */
public class ThreadSync {

    public static void main(String[] args) {
        // 有负数线程不安全(买票例子)
        BuyTicket buyTicket = new BuyTicket();
        new Thread(buyTicket, "me = ").start();
        new Thread(buyTicket, "you = ").start();
        new Thread(buyTicket, "scalpers = ").start();

        // 银行取钱不安全例子
        Account account = new Account(100, "结婚基金");
        Drawing you = new Drawing(account, 50, "你");
        Drawing girl = new Drawing(account, 100, "你的妻子");

        you.start();
        girl.start();

        // 集合线程不安全例子
        List<String> strings = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            new Thread(() -> {
                synchronized (strings) {
                    strings.add(Thread.currentThread().getName());
                }
            }).start();

        }

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(strings.size());

    }
}

class BuyTicket implements Runnable {

    // 票
    private int ticketNum = 10;

    private boolean flag = true;

    @Override
    public void run() {
        // 买票
        while (flag) {
            try {
                buy();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }


    }

    /**
     * 同步方法(保证线程安全)
     *
     * @throws InterruptedException
     */
    private synchronized void buy() throws InterruptedException {
        if (ticketNum <= 0) {
            flag = false;
            return;
        }

        Thread.sleep(100);
        System.out.println(Thread.currentThread().getName() + "拿到" + ticketNum--);
    }
}

class Account {
    int money;
    String name;

    Account(int money, String name) {
        this.money = money;
        this.name = name;

    }

}

class Drawing extends Thread {

    private Account account;
    private int drawMoney;
    private int nowMoney;


    public Drawing(Account account, int drawMoney, String name) {
        super(name);
        this.account = account;
        this.drawMoney = drawMoney;
    }

    @Override
    public void run() {

        // 同步块 增删改对象
        synchronized (account) {
            if (account.money - drawMoney < 0) {
                System.out.println(Thread.currentThread().getName() + "钱不够,取不了");
                return;
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            account.money = account.money - drawMoney;
            nowMoney = nowMoney + drawMoney;

            System.out.println(account.name + "余额为" + account.money);
            System.out.println(this.getName() + "手里的钱" + nowMoney);
        }
    }

}

